package mdt.gui;

import mdt.figure.FigNodeEditable;
import mdt.figure.FigShapedEdge;
import net.miginfocom.swing.MigLayout;
import org.tigris.gef.presentation.Fig;
import org.tigris.gef.presentation.FigEdge;
import org.tigris.gef.presentation.FigText;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.lang.reflect.Method;

/**
 * Created by xiaobyu on 7/19/2016.
 */
public class TextAttributePanel extends AttributePanel {

    private final int MAX = 64;

    JCheckBox jrb;

    public TextAttributePanel() {

        addSeparator("Text Margins");

        jrb = new JCheckBox("Force minimum size");
        jrb.setSelected(false);
        jrb.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                if (jrb.isSelected()) {
                    forceMinimumSize();
                }
            }
        });
        add(jrb, "gap para, span 4, wrap");

        int left = getMargin(firstFig, "Left");
        int right = getMargin(firstFig, "Right");
        int top = getMargin(firstFig, "Top");
        int bottom = getMargin(firstFig, "Bot");

        add(new JLabel("Left"), "gap para");
        add(createJTF("Left", left));

        add(new JLabel("Right"));
        add(createJTF("Right", right), "wrap");

        add(new JLabel("Top"), "gap para");
        add(createJTF("Top", top));

        add(new JLabel("Bottom"));
        add(createJTF("Bot", bottom), "wrap");

    }

    private void forceMinimumSize() {
        for (Fig fig : figs) {
            if (fig instanceof FigText) {
                Dimension textMinSize = fig.getMinimumSize();
                fig.setWidth(textMinSize.width);
                fig.setHeight(textMinSize.height);
                fig.damage();
            } else if (fig instanceof FigNodeEditable) {
                ((FigNodeEditable) fig).shrinkToMinimumBounds();
                fig.damage();
            }
        }
    }

    public JTextField createJTF(String type, int value) {
        JTextField jtf = new JTextField(String.valueOf(value), 6);
        jtf.getDocument().addDocumentListener(new MarginDocumentListener(jtf, type));
        return jtf;
    }

    public void initLayout() {
        setLayout(new MigLayout("", "[][fill,grow]25[][fill,grow]", ""));
    }

    public int getMargin(Fig fig, String type) {
        try {
            if (fig instanceof FigNodeEditable) {
                fig = ((FigNodeEditable)fig).getFigText();
            }
            Method m = fig.getClass().getMethod("get" + type + "Margin");
            return (int) m.invoke(fig);
        } catch (Exception e) {
            return -1;
        }
    }

    private class MarginDocumentListener implements DocumentListener {

        JTextField jta;
        String type;
        public MarginDocumentListener(JTextField jta, String type) {
            this.jta = jta;
            this.type = type;
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            updateMargin();

        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            updateMargin();
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            updateMargin();
        }

        private void updateMargin() {
            String text = jta.getText();
            int margin = 0;
            try {
                margin = Integer.parseInt(text);
                if (margin < 0) {
                    margin = 0;
                } else if (margin > MAX) {
                    margin = MAX;
                }
            } catch (Exception e) {
            }

            if (!text.equals(String.valueOf(margin))) {
                jta.setForeground(Color.red);
                return;
            } else {
                jta.setForeground(Color.black);
            }

            for (Fig fig : figs) {
                Fig textFig = fig;
                if (fig instanceof FigNodeEditable) {
                    textFig = ((FigNodeEditable)fig).getFigText();
                }
                try {
                    Method m = textFig.getClass().getMethod("set" + type + "Margin", int.class);
                    m.invoke(textFig, margin);
                    if (jrb.isSelected()) {
                        forceMinimumSize();
                    } else {
                        if (fig instanceof FigNodeEditable) {
                            ((FigNodeEditable) fig).updateBounds();
                        } else if (fig instanceof FigShapedEdge){
                            ((FigNodeEditable) ((FigEdge)fig).getFig()).updateBounds();
                        } else {
                            fig.calcBounds();
                        }
                    }
                    fig.damage();
                } catch (Exception e) {

                }
            }
        }
    }
}
